function questionFormBuilder() {
    const rowList = [];
    let quesTypeList = [];
    queryQuestionTypeList(({Result}) => quesTypeList = Result);

    const $dom = $(`
        <div style="display: flex;flex-direction: row;flex-wrap:nowrap;">
            <div style="width: 50%;;padding-right: 12px;border-right: 1px solid #E9EFF4;">
                <div data-wrap="temp" class="mask-account"></div>
                <a data-btn="add" href="javascript:" class="c-btn c-btn-white m5">新增</a>
            </div>
            <div style="width: 50%;padding-left: 12px">
                <div data-wrap="view" class="mask-account"></div>
            </div>
        </div>
    `)

    const $tempWrap = $dom.find('[data-wrap="temp"]');
    const $viewWrap = $dom.find('[data-wrap="view"]');
    const $addBtn = $dom.find('[data-btn="add"]');

    $addBtn.on("click", () => {
        addOrUpdRowDialog("新增", {}, data => {
            addRow(data);
        });
    });


    return {
        $dom,
        addRow,
        rowList
    }

    /**
     * 新增行
     * @param data
     */
    function addRow(data) {
        if (!quesTypeList || !quesTypeList.length) {
            setTimeout(() => {
                addRow(data);
            }, 200);

            return false;
        }

        data = {
            rowId: null,
            rowTitle: null,
            rowPlaceholder: null,
            rowType: null,
            rowScope: null,
            rowMustFlag: 0,
            sortIndex: rowList.length + 1,
            ...data
        }

        //获取数据插入位置
        let index = 0;
        rowList.forEach(item => {
            if (item.sortIndex > data.sortIndex) {
                return false;
            }
            index += 1;
        });

        rowList.splice(index, 0, data);

        //重新整理好排序
        let sortIndex = 1;
        rowList.forEach(item => {
            item.sortIndex = sortIndex;
            sortIndex += 1;
        });

        tempBuild();
        viewBuild();
    }

    /**
     * 删除行
     * @param data
     */
    function delRow(data) {
        rowList.splice(rowList.findIndex(item => item === data), 1);

        //重新整理好排序
        let sortIndex = 1;
        rowList.forEach(item => {
            item.sortIndex = sortIndex;
            sortIndex += 1;
        });

        tempBuild();
        viewBuild();
    }

    function upRow(data) {
        const index = rowList.findIndex(item => item === data);
        if (index === -1 || index === 0) {
            return;
        }

        const preData = rowList[index - 1];
        rowList.splice(index - 1, 1, data);
        rowList.splice(index, 1, preData);

        //重新整理好排序
        let sortIndex = 1;
        rowList.forEach(item => {
            item.sortIndex = sortIndex;
            sortIndex += 1;
        });

        tempBuild();
        viewBuild();
    }

    function downRow(data) {
        const index = rowList.findIndex(item => item === data);
        if (index === -1 || index === rowList.length - 1) {
            return;
        }

        const nextData = rowList[index + 1];

        rowList.splice(index, 1, nextData);
        rowList.splice(index + 1, 1, data);

        //重新整理好排序
        let sortIndex = 1;
        rowList.forEach(item => {
            item.sortIndex = sortIndex;
            sortIndex += 1;
        });

        tempBuild();
        viewBuild();
    }


    function tempBuild() {
        $tempWrap.html("");
        let index = 0;
        rowList.forEach(data => {
            const quesType = quesTypeList.filter(({type}) => data.rowType === type)[0];
            const $row = $(`
                <div>
                    <span class="mask-account-tit" style="line-height: 35px">${data.rowMustFlag === 1 ? '<sub style="color: red;">*</sub>' : ''} ${data.rowTitle}</span>
                    <div class="input-select" style="border: 0; display: flex;padding: 0">
                        <div style="flex-grow: 1;line-height: 35px">${quesType.title}类型</div>
                        <div style="width: 170px;flex-basis: content;">
                            <a data-btn="up" href="javascript:" class="c-btn c-btn-white">↑</a>
                            <a data-btn="down" href="javascript:" class="c-btn c-btn-white">↓</a>
                            <a data-btn="editRow" href="javascript:" class="c-btn c-btn-white">编辑</a>
                            <a data-btn="delRow" href="javascript:" class="c-btn btn-red">删除</a>
                        </div>
                    </div>
                </div>
            `)

            const $upBtn = $row.find('[data-btn="up"]');
            const $downBtn = $row.find('[data-btn="down"]');
            const $editBtn = $row.find('[data-btn="editRow"]');
            const $delBtn = $row.find('[data-btn="delRow"]');

            $upBtn.on("click", () => {
                upRow(data);
            });

            $downBtn.on("click", () => {
                downRow(data);
            });

            $editBtn.on("click", () => {
                addOrUpdRowDialog("编辑", data, (newData) => {
                    rowList.splice(rowList.findIndex(item => item === data), 1);
                    addRow(newData);
                });
            });

            $delBtn.on("click", () => {
                return $.dialog("是否确定删除该字段", {
                    title: "删除",
                    width: "300px",
                    ok: () => {
                        delRow(data);
                    }
                })
            });

            if (index === 0) {
                $row.css({margin: 0})
                $upBtn.remove();
            }
            if (index === rowList.length - 1) {
                $downBtn.remove();
            }

            $tempWrap.append($row);

            index += 1;
        });
    }

    function viewBuild() {
        $viewWrap.html("");
        let index = 0;

        rowList.forEach(data => {
            const $row = $(`
                <div>
                    <span class="mask-account-tit">${data.rowMustFlag === 1 ? '<sub style="color: red;">*</sub>' : ''} ${data.rowTitle}</span>
                    <div data-wrap="sel" class="input-select"></div>
                </div>
            `);

            $viewWrap.append($row);

            if (index === 0) {
                $row.css({margin: 0})
            }

            const rowType = data.rowType;
            const $wrap = $row.find('[data-wrap="sel"]');

            if (rowType === 1) {
                $wrap.html(`<input type="text" placeholder="${data.rowPlaceholder}">`)
            }
            if (rowType === 2) {
                $wrap.html(`<textarea placeholder="${data.rowPlaceholder}"></textarea>`)
            }

            if (rowType === 3) {
                const $sel = $.getSelect("", [
                    {name: "请选择", value: ""},
                    ...data.rowScope.split(",").map(val => {
                        return {name: val, value: val}
                    })
                ]);

                $wrap.replaceWith($sel);
            }

            if (rowType === 4) {
                const $input = $(`<input type="text" placeholder="${data.rowPlaceholder}">`);

                $wrap.html($input);
                $wrap.append(`<i class="bi-chevron-down"></i>`);

                laydate.render({
                    elem: $input[0],
                    type: "date"
                });
            }


            if (rowType === 5) {
                $wrap.css({border: 0, padding: 0});
                $wrap.append(getUploadImgWidget({}))
            }

            if (rowType === 6) {
                $wrap.css({border: 0, padding: 0});
                $wrap.append($.getCitySelect({
                    level: 2
                }))
            }


            index += 1;
        });
    }

    function addOrUpdRowDialog(dialogTitle, data, callback = Function()) {
        data = {
            rowId: null,
            rowTitle: null,
            rowPlaceholder: null,
            rowType: null,
            rowScope: null,
            rowMustFlag: 0,
            sortIndex: rowList.length + 1,
            ...data
        }

        const $form = $(`
            <form class="mask-account">
                <div style="margin: 0">
                    <span class="mask-account-tit"><sub style="color: red;">*</sub> 行标题</span>
                    <span class="input-select">
                        <input name="rowTitle" value="${data.rowTitle || ''}" type="text"  placeholder="请输入行标题"/>
                    </span>
                </div>
                <div>
                    <span class="mask-account-tit">行提示</span>
                    <span class="input-select">
                        <input name="rowPlaceholder" value="${data.rowPlaceholder || ''}" type="text"  placeholder="请输入行提示"/>
                    </span>
                </div>
                <div>
                    <span class="mask-account-tit"><sub style="color: red;">*</sub> 是否必填</span>
                    <span data-select="rowMustFlag"></span>
                </div>
                <div>
                    <span class="mask-account-tit"><sub style="color: red;">*</sub> 表单类型</span>
                    <span data-select="rowType"></span>
                </div>
            </form>
        `);

        const $rowMustFlagSel = $.getSelect("rowMustFlag", [
            {name: "非必填", value: 0},
            {name: "必填", value: 1}
        ])
        $rowMustFlagSel.setValue(data.rowMustFlag);
        $form.find('[data-select="rowMustFlag"]').append($rowMustFlagSel);

        const $rowTypeSel = $.getSelect("rowType", [
            {name: "请选择", value: ''},
            ...quesTypeList.map(({type, title}) => {
                return {name: title, value: type};
            })
        ], ({value}) => {
            if (!value) {
                return;
            }
            value = Number(value);
            const {scopeFlag} = quesTypeList[quesTypeList.findIndex(item => item.type === value)];
            if (scopeFlag === 1) {
                const $dom = $(`
                    <div data-wrap="rowScope">
                        <span class="mask-account-tit"><sub style="color: red;">*</sub> 值范围</span>
                        <span class="input-select">
                            <input name="rowScope" value="${data.rowScope || ''}" type="text"  placeholder="请输入值范围，逗号分隔"/>
                        </span>
                    </div>
                `);

                $form.append($dom);

            } else {
                $form.find('[data-wrap="rowScope"]').remove();
                data.rowScope = null;
            }
        })
        $form.find('[data-select="rowType"]').append($rowTypeSel);
        if (data.rowType) {
            $rowTypeSel.find(`li[data-value=${data.rowType}]`).click();
        }


        return $.dialog($form, {
            title: dialogTitle || "操作",
            width: "600px",
            ok: () => {
                data = {
                    ...data,
                    ...$.getFormData($form)
                };


                if (!data.rowTitle) {
                    $.toast("标题不能为空");
                    return false;
                }

                if (data.rowMustFlag === "") {
                    $.toast("请选择是否必填");
                    return false;
                } else {
                    data.rowMustFlag = Number(data.rowMustFlag);
                }

                if (data.rowType === "") {
                    $.toast("请选择表单类型");
                    return false;
                } else {
                    data.rowType = Number(data.rowType);

                    const {scopeFlag} = quesTypeList[quesTypeList.findIndex(item => item.type === data.rowType)];
                    if (scopeFlag === 1 && !data.rowScope) {
                        $.toast("值范围不能为空");
                        return false;
                    }
                }

                callback(data);
            }
        })
    }

    function queryQuestionTypeList(callback = Function()) {
        return $.sApi({
            url: "/api/Question/queryQuestionTypeList"
        }, callback)
    }

}